from storehouse.relationCheckers import getInventoriedStorehouses
from storehouse.exceptions import StorehouseUnderINventory
from datetime import datetime
from storehouse.relationCheckers import hasStorehouseUnappliedInventory
from operator import isSequenceType

from storehouse.relationCheckers import calculatePrice, sourceCapacityTest,\
    destinationCapacityTest, isPersonStorehouseManager,\
    isPersonLogisticSupervisor, isPersonLogistic, isOrderCancelable,\
    OrderCanBeArchived, isPersonStorehouseStaff
from django.contrib.auth.models import *
from storehouse.models import barcode
from django.contrib.auth.models import check_password
from django.db.models.fields import BooleanField
from storehouse.models import document,order_product,document_type,product_category,order_state,\
    cooperation_group,partner_status,currency,storehouse,user_status,storehouse_volume,\
    document_modification,palette_type, person
from storehouse.models import inventory_product
from storehouse.models import storehouse_product
from storehouse.models import inventory_product_diff

from django.contrib.auth.admin import UserAdmin
from django.contrib import admin
from django.contrib.auth.models import *
from storehouse.models import *
from django.utils.translation import ugettext, ugettext_lazy as _
from django.contrib import admin
from django.forms.widgets import CheckboxInput
from django import forms
from django.forms import formsets
from django.db.models import Q

from django.db import IntegrityError
from storehouse.stateModifiers import sourceCapacityBookOut,\
    destinationCapacityBookIn, OrderCancel, orderArchive, completeRW, completePW,\
    completePZ, completeWZ
import sys
from django.shortcuts import redirect
from django.http import HttpResponseRedirect

from django.views.decorators.csrf import csrf_protect
from django.contrib.admin.options import csrf_protect_m
from django.db import transaction
from storehouse.relationCheckers import getUserStorehouses
from storehouse.messages import *
from django.core.exceptions import ValidationError

from django.forms.models import ModelForm
from storehouse.relationCheckers import orderDestinationCapacityTest,orderSourceCapacityTest

class newUserAdmin( UserAdmin ):
    list_filter = ('status_id',)
    add_fieldsets =(
              (None, {'fields': ('username', 'password1','password2','status_id')}),
          )

class UnitAdmin(admin.ModelAdmin):
        list_display = ('name','symbol')
class Document_typeAdmin(admin.ModelAdmin):
    list_display = ('name','symbol')
class productAdmin(admin.ModelAdmin):
    list_display = ('name','symbol','is_carefully','category')
    list_filter = ('category',)
    search_fields = ['name','symbol']
class tax_rateAdmin(admin.ModelAdmin):
    list_display = ('symbol','country','value')
    list_filter = ('country',)
    search_fields = ('symbol',)

class Storehouse_productAdmin(admin.ModelAdmin):
    actions =['liquidateProduct']
    list_filter = ('palete_type','product__category__name')
    search_fields = ('product__name','barcode__barcode_no')

    
    def change_view(self, request, object_id, form_url='', extra_context=None):
        
        if request.user.has_perm(u'storehouse.storehouse_product_changer_r'):
            return admin.ModelAdmin.change_view(self, request, object_id, form_url=form_url, extra_context=extra_context)
        else :
            return HttpResponseRedirect("/error_view/?error_message=%s\n" %"Nie mozesz edytowac")

    def queryset(self, request):
        if request.user.is_superuser:
            return storehouse_product.objects.all()
        try:
            person_o =  person.objects.get(user = user.objects.get(user_ptr = request.user).id)
            if isPersonStorehouseManager(person_in=person_o):
                storehouse_o = storehouse.objects.get(manager = person_o)
                if hasStorehouseUnappliedInventory(storehouse_o):
                   pass# raise StorehouseUnderINventory(STOREHOUSE_UNDER_INVENTORY)
                return storehouse_product.objects.filter(storehouse= storehouse_o)
        except:
            raise
        return storehouse_product.objects.get_empty_query_set()
    
    @transaction.commit_on_success
    def liquidateProduct(self,request,queryset):
        person_o =  person.objects.get(user = user.objects.get(user_ptr = request.user).id)
        if hasStorehouseUnappliedInventory(storehouse.objects.get(manager = person_o)):
            return HttpResponseRedirect("/error_view/?error_message=%s\n" %STOREHOUSE_UNDER_INVENTORY)
        for query_i in queryset:
            liquidation_o = liquidation.objects.create(
                                                           product = query_i.product,
                                                           palette_type = query_i.palete_type,
                                                           barcode  = query_i.barcode,
                                                       )
            liquidation_o.save()
            document_o = document.objects.create(
                                         document_type = document_type.objects.get(symbol = 'PL'),
                                         creator = user.objects.get(user_ptr = request.user),
                                         storehouse  = storehouse.objects.get(manager = person_o),
                                         liquidation = liquidation_o,
                                         )

            document_o.save()

            query_i.delete()
            liquidation_storehouse = storehouse.objects.get(manager = person_o)
            illegal_states = order_state.objects.filter(name__in = ['Zrealizowany','Anulowany'])
            storehouse_orders = order.objects.filter((Q(storehouse_from = liquidation_storehouse)|\
                Q( storehouse_to = liquidation_storehouse))).exclude(state__in = illegal_states).distinct()

            raw_orders_to_check = [ ord_prod_i.order.id for ord_prod_i in order_product.objects.filter(order__in = storehouse_orders,\
                product = query_i.product,palette_type = query_i.palete_type)]
            orders_to_check = order.objects.filter(id__in = raw_orders_to_check).distinct()

            for order_to_check in orders_to_check:
                try:
                    orderDestinationCapacityTest(order_to_check)
                    orderSourceCapacityTest(order_to_check)
                except:
                    order_to_check.is_achievable = False
                    order_to_check.save()
                
             
        self.message_user(request, "Zlikwidowano")
        self.short_description = "Likwiduj produkty"

class PartnerModelForm(ModelForm):
    class Meta:
        model = partner
        
class PartnerAdmin(admin.ModelAdmin):
    form = PartnerModelForm
    @csrf_protect_m
    @transaction.commit_on_success
    def change_view(self, request, object_id, form_url='', extra_context=None):
        if request.method == 'POST':
            if request.POST.has_key('_preview'):
                partnerModelForm_o = PartnerModelForm(request.POST)
                return HttpResponseRedirect("/admin/storehouse/address_view/%s" %partnerModelForm_o.data['address'] )
        return admin.ModelAdmin.change_view(self, request, object_id, form_url=form_url, extra_context=extra_context)

class Storehouse_volumeInline(admin.TabularInline):
    model = storehouse_volume

class StorehouseModelForm(ModelForm):
    class Meta:
        model = storehouse
        
class StorehouseAdmin(admin.ModelAdmin):
    form = StorehouseModelForm
    inlines = [Storehouse_volumeInline,]
    list_display = ('name','symbol','manager','address')
    search_fields = ('name','symbol','manager__first_name','manager__last_name')
    def change_view(self, request, object_id, form_url='', extra_context=None):
        if not hasStorehouseUnappliedInventory(storehouse.objects.get(id=object_id)):
            if request.method == 'POST':
                if request.POST.has_key('_preview'):
                    storehouseModelForm_o = StorehouseModelForm(request.POST)
                    return HttpResponseRedirect("/admin/storehouse/address_view/%s" %storehouseModelForm_o.data['address'] )
            return admin.ModelAdmin.change_view(self, request, object_id, form_url=form_url, extra_context=extra_context)
        else:
            return HttpResponseRedirect("/error_view/?error_message=%s\n" %STOREHOUSE_UNDER_INVENTORY )    
    def get_form(self, request, obj=None, **kwargs):
        form = super(StorehouseAdmin,self).get_form(request, obj,**kwargs)
        try:
            storehouse_staff = person.objects.filter(user__in= user.objects.filter(user_ptr__in=User.objects.filter(groups__name = 'Magazynierzy')))

        except:
            storehouse_staff =   person.objects.get_empty_query_set()


        try:
            storehouse_managers = person.objects.filter(user__in= user.objects.filter(user_ptr__in=User.objects.filter(groups__name = 'Managerowie Magazynow')))
        except:
            storehouse_managers = person.objects.get_empty_query_set()

        form.base_fields['person'] = forms.ModelMultipleChoiceField(queryset= storehouse_staff)
        form.base_fields['manager'] = forms.ModelChoiceField(queryset= storehouse_managers)

        return form

class CurrencyAdmin(admin.ModelAdmin):
    list_display = ('name','symbol_path')
    search_fields = ('name','symbol_path')

class Storehouse_volumeAdmin(admin.ModelAdmin):
    pass
#TODO restrict to Storehouse manager
#filter documents storehouse
#create document when create this

#check del quantity
#todo remove liquidation managers ?

class LiquidationAdmin(admin.ModelAdmin):
    def queryset(self, request):
        try:
            person_o =  person.objects.get(user = user.objects.get(user_ptr = request.user).id)
        except:
            return liquidation.objects.get_empty_query_set()
        if request.user.is_superuser:
            return liquidation.objects.all()
        if isPersonStorehouseManager(person_in=person_o):
            storehouse_o = storehouse.objects.get(manager = person_o)
            return document.objects.filter(storehouse= storehouse_o).select_related('liquidation')
        return liquidation.objects.get_empty_query_set()
    @csrf_protect_m
    def change_view(self, request, object_id, form_url='', extra_context=None):
        if request.user.has_perm(u'storehouse.sliquidation change_r'):
            return admin.ModelAdmin.change_view(self, request, object_id, form_url=form_url, extra_context=extra_context)
        return HttpResponseRedirect("/order_view/?order_id=%s" %object_id )    
    


class Inventory_productInline(admin.TabularInline):
    model = inventory_product
class Inventory_productAdmin(admin.ModelAdmin):
    pass
class InventoryAdmin(admin.ModelAdmin):
    exclude = ('is_applied' ,'is_canceled','name')
    inlines = [Inventory_productInline,]
    actions = ['applyInventory','cancelInventory','uncancelInventory']
    list_filter = ('is_applied','is_canceled')
    
    @csrf_protect_m
    def add_view(self, request, form_url='', extra_context=None):
        try:
            person_o = person.objects.get(user = user.objects.get(user_ptr = request.user).id)
            storehouse_o = storehouse.objects.get(manager = person_o)
        except:
            return HttpResponseRedirect("/error_view/?error_message=%s\n" %NOT_STOREHOUSE_ADMIN )
        if hasStorehouseUnappliedInventory(storehouse_o):
            return HttpResponseRedirect("/error_view/?error_message=%s\n" %STOREHOUSE_UNDER_INVENTORY)
        return admin.ModelAdmin.add_view(self, request, form_url=form_url, extra_context=extra_context)
    @transaction.commit_on_success
    def save_model(self, request, obj, form, change):
        try:
            person_o = person.objects.get(user = user.objects.get(user_ptr = request.user).id)
            storehouse_o = storehouse.objects.get(manager = person_o)
        except:
            raise

        obj.save()
        try:
            if not change:

                newDoc = document.objects.create(
                    document_type = document_type.objects.get(symbol = 'REM'),
                    creator = user.objects.get(user_ptr = request.user),
                    storehouse  = storehouse_o,
                    inventory = obj,
                )
                newDoc.save()
                obj.name = "Inwentaryzacja|%s|%s " %(storehouse_o,newDoc.creationDate)
                obj.save

            else:
                doc_o = document.objects.get(inventory = obj)
                modify_o = document_modification.objects.create(
                    document = doc_o,
                    user = user.objects.get(user_ptr = request.user),
                    )
                modify_o.save()
        except:
            raise
           
        obj.save()
    @transaction.commit_on_success
    def save_related(self, request, form, formsets, change):
        for formset_ob in formsets:
            instances = formset_ob.save(commit =False)

            for instance_i in instances:
                instance_i.save()


    
    @transaction.commit_on_success
    def applyInventory(self,request,queryset):
    
        if len(queryset)>1:
            self.message_user(request,u"Mozna zatwierdzic na raz tylko jedna inwentaryzacje")
            return
        
        for inventory_i in queryset:
             if inventory_i.is_applied:
                 return HttpResponseRedirect("/error_view/?error_message=%s\n" %INVENTORY_IS_APPLIED)
             elif  inventory_i.is_canceled :
                 return HttpResponseRedirect("/error_view/?error_message=%s\n" %CANCELED_INVENTORY)
            #TODO change this it is extremly slow O(MN)
             inventory_document = document.objects.get(inventory = inventory_i)
             storehouse_products = storehouse_product.objects.filter(storehouse = inventory_document.storehouse)
             inventory_products = inventory_product.objects.filter(inventory = inventory_i)
             inventory_i.is_applied = True 
             for inventory_product_i in inventory_products:
                 isInStorehouse = False
                 for i in range(len(storehouse_products)):
                      
                     intersect_product = storehouse_products[i]
                     if intersect_product.barcode.barcode_no == inventory_product_i.barcode.barcode_no \
                                       and intersect_product.palete_type == inventory_product_i.palete_type\
                                       and intersect_product.product == inventory_product_i.product :
                         isInStorehouse = True
                         storehouse_products = storehouse_products.exclude(id  =  intersect_product.id )
                         break
                         
                     
                 
                 
                 
                 if not isInStorehouse:
                     added_product = storehouse_product.objects.create(
                                                                           storehouse = inventory_document.storehouse,
                                                                           product = inventory_product_i.product,
                                                                           palete_type = inventory_product_i.palete_type,
                                                                           barcode  =inventory_product_i.barcode
                                                                       )
                     added_product.save()
                     added_diff = inventory_product_diff.objects.create(
                                                                            inventory = inventory_i,
                                                                            deficit =False,
                                                                            product = inventory_product_i.product,
                                                                            palete_type = inventory_product_i.palete_type,
                                                                            barcode  =inventory_product_i.barcode
                                                                        )
                     added_diff.save()
             for storehouse_product_to_del in storehouse_products:
                 added_diff = inventory_product_diff.objects.create(
                                                                    inventory = inventory_i,
                                                                    deficit =True,
                                                                    product = storehouse_product_to_del.product,
                                                                    palete_type = storehouse_product_to_del.palete_type,
                                                                    barcode  =storehouse_product_to_del.barcode
                                                                    )
                 storehouse_product_to_del.delete()
             #TODO check orders
             illegal_states = order_state.objects.filter(name__in = ['Zrealizowany','Anulowany'])
             storehouse_orders = order.objects.filter(Q(storehouse_from = inventory_document.storehouse)|Q(storehouse_to = inventory_document.storehouse)).exclude(state__in = illegal_states)

             for storehouse_order in storehouse_orders:
                 try:
                     orderDestinationCapacityTest(storehouse_order)
                     orderSourceCapacityTest(storehouse_order)
                 except:
                     storehouse_order.is_achievable = False
                     storehouse_order.save()


             
             inventory_i.save()
             
             return HttpResponseRedirect("/inventory/?inventory_id=%i" % (inventory_i.id))
            
    @transaction.commit_on_success    
    def cancelInventory(self,request,queryset):
        allInventories = 0
        canceledInventories = 0
        for inventory_i in queryset:
            allInventories += 1
            if  not inventory_i.is_applied:
                canceledInventories +=1
                inventory_i.is_canceled = True
                inventory_i.save()
        self.short_description = u"Anuluj Inwentaryzacje"
        self.message_user(request,u"Zostalo anaulowanych %i na %i inwentaryzacji" %(canceledInventories,allInventories))
    @transaction.commit_on_success
    def uncancelInventory(self,request,queryset):
        allInventories = 0
        uncanceledInventories = 0
        if len(queryset)>1:
            self.message_user(request,u"Mozna Aktywowac na raz tylko jedna inwentaryzacje")
            return
        for inventory_i in queryset:
            allInventories += 1
            if  not inventory_i.is_applied:
                uncanceledInventories +=1
                inventory_i.is_canceled = False
                inventory_i.save()
        self.short_description = u"Aktywuj Inwentaryzacje"
        self.message_user(request,u"Zostalo aktywowanych %i na %i inwentaryzacji" %(uncanceledInventories,allInventories))   
        

class OrderInline_formset(forms.models.BaseInlineFormSet):
    
    def is_valid(self):
        return forms.models.BaseInlineFormSet.is_valid(self)
    def clean(self):
        forms.models.BaseInlineFormSet.clean(self)
        order_products_instances = []
        products_counter = 0

        for form in self.forms:
            print " xxxxxxxxxxxxxxxxxxx",self.instance.partner_from
            print "get Form!!!"
            try:
                if form.is_valid():
                    order_products_instances.append(form.save(commit = False))
            except:

                print " OrderInline_formset.clean ",sys.exc_info()

            if order_products_instances:
                print "OBJECTS GET"
                products_counter = products_counter+1
                try:
                    print "OOOOOOOOOOOOORRRRRRRRRRRRR"
                    order_o = self.instance
                    
                    #print "Poszo",order_o
                    try:
                        order_o.storehouse_to   = storehouse.objects.get(manager = self.instance.partner_from)
                    except:
                        pass
                    try:
                        order_o.storehouse_from = storehouse.objects.get(manager = self.instance.partner_to)
                    except:
                        pass
                   # print "OOORRRDER:::::::::",order_o," PO_ORDER"
                    
                    print "STOR_FROM",order_o.storehouse_from
                    if order_o.storehouse_from:
                        print "SRC_CAP_TEST"
                        sourceCapacityTest(order_o,order_products_instances,False)
                    print "STOR_TO",order_o.storehouse_to
                    if order_o.storehouse_to:
                        print "DST_CAP_TEST"
                        destinationCapacityTest(order_o,order_products_instances,False)


                except ValidationError:
                    print "VE",sys.exc_info()
                    raise
                except:
                    print "OTHER_______",sys.exc_info()

        if products_counter == 0:
            raise ValidationError("Zamowienie musi zawierac conajmniej jeden produkt")
                
class Order_productInline(admin.TabularInline):
    formset = OrderInline_formset
    model = order_product
    exclude = ['barcode']
    
    
class OrderModelForm(ModelForm):
    class Meta:
        model = order
    def clean(self):
        print "Order_form_clean"
        return ModelForm.clean(self)

class OrderAdmin(admin.ModelAdmin):
    form = OrderModelForm
    inlines = [Order_productInline,]
    exclude = ('state','is_archived','is_achievable','price','system_user','order_type','storehouse_from','storehouse_to')
    actions =['cancelOrder','archiveOrder']
    list_filter = ('state','is_archived','is_achievable')
    search_fields = ('creation_date',)
    last_obj = None
    def queryset(self, request):
        try:
            person_o =  person.objects.get(user = user.objects.get(user_ptr = request.user).id)
        except:
            return order.objects.get_empty_query_set()

        if request.user.is_superuser or request.user.has_perm(u'storehouse.supervising order'):
            return order.objects.all()
        if request.user.has_perm(u'storehouse.view own orders'):
            return order.objects.filter(system_user =  user.objects.get(user_ptr = request.user))
        if request.user.has_perm(u'storehouse.order storehouse man'):
            try:
                user_storehouses = getUserStorehouses(request.user)
                return order.objects.filter(Q(storehouse_from__in = user_storehouses)|Q(storehouse_to__in = user_storehouses))
            except:
                pass
        return order.objects.get_empty_query_set()
    @csrf_protect_m
    @transaction.commit_on_success
    def add_view(self, request, form_url='', extra_context=None):
        print "FORM",form_url
        return admin.ModelAdmin.add_view(self, request, form_url=form_url, extra_context=extra_context)
    @csrf_protect_m
    @transaction.commit_on_success
    def change_view(self, request, object_id, form_url='', extra_context=None):
        order_to_change = order.objects.get(id = object_id)
        not_change_states = order_state.objects.filter(name__in = ['Zrealizowany','Oczekujacy na PW'])
        if request.user.has_perm(u'storehouse.order change_r') and (not order_to_change.is_archived) and (not order_to_change.state in not_change_states):
            return admin.ModelAdmin.change_view(self, request, object_id, form_url=form_url, extra_context=extra_context)
        return HttpResponseRedirect("/order_view/?order_id=%s" %object_id ) 

    def get_form(self, request, obj=None, **kwargs):
        form = super(OrderAdmin,self).get_form(request, obj,**kwargs)
        transport_partners = None
        try:
            from_persons =person.objects.filter(Q(partner__in= \
                                 partner.objects.filter(cooperation_groups__in = cooperation_group.objects.filter(name = 'Dostawcy')).exclude(status__name = 'Wydzial Firmy'))\
                                |Q(id__in = person.objects.filter(user__in= user.objects.filter(user_ptr__in=User.objects.filter(groups__name = 'Managerowie Magazynow'))))
                                 ).distinct()

        except:
            from_persons = person.objects.get_empty_query_set()

        try:
            to_persons =person.objects.filter(Q(partner__in= \
                                 partner.objects.filter(cooperation_groups__in = cooperation_group.objects.filter(name = 'Odbiorcy')).exclude(status__name = 'Wydzial Firmy'))\
                                |Q(id__in = person.objects.filter(user__in= user.objects.filter(user_ptr__in=User.objects.filter(groups__name = 'Managerowie Magazynow'))))
                                 ).distinct()
        except:
            to_persons = person.objects.get_empty_query_set()

        try:
            transport_partners =partner.objects.filter(cooperation_groups__in = cooperation_group.objects.filter(name = 'Transport'))
        except:
            transport_partners =partner.objects.get_empty_query_set()


        form.base_fields['partner_from'] = forms.ModelChoiceField(queryset= from_persons)
        form.base_fields['partner_to'] = forms.ModelChoiceField(queryset= to_persons)
        form.base_fields['transport'] = forms.ModelChoiceField(queryset= transport_partners)
        return form
    @transaction.commit_on_success
    def save_model(self, request, obj, form, change):
       # raise ValidationError("WTF no save")
        if not change:
            obj.system_user = user.objects.get(user_ptr = request.user)
        else:
            modify_o = order_modification(order=obj,user=user.objects.get(user_ptr = request.user))
            modify_o.save()
        form.system_user = user.objects.get(user_ptr = request.user)
        obj.is_archived = False
        obj.is_achievable = True
        obj.price=0
        isFromStorehouseManager = isPersonStorehouseManager(person_in = obj.partner_from)
        isToStorehouseManager = isPersonStorehouseManager(person_in = obj.partner_to)
        if isFromStorehouseManager and isToStorehouseManager:
            obj.order_type = order_type.objects.get(name = 'Przesuniecie MM')
            obj.state = order_state.objects.get(name  ='Oczekujacy na RW')
            obj.storehouse_to   = storehouse.objects.get(manager = obj.partner_to)
            obj.storehouse_from = storehouse.objects.get(manager = obj.partner_from)

        elif isFromStorehouseManager and  not isToStorehouseManager:
            obj.order_type = order_type.objects.get(name = 'Sprzedaz')
            obj.state = order_state.objects.get(name  ='Oczekujacy na WZ')
            obj.storehouse_from = storehouse.objects.get(manager = obj.partner_from)
        elif not isFromStorehouseManager and isToStorehouseManager:
            obj.order_type = order_type.objects.get(name = 'Kupno')
            obj.state = order_state.objects.get(name  ='Oczekujacy na PZ' )
            obj.storehouse_to   = storehouse.objects.get(manager = obj.partner_to)
        else:
            #TODO co z transportem?
            pass
        self.last_obj = obj
        obj.save()
    @transaction.commit_on_success
    def save_related(self, request, form, formsets, change):

        for formset_ob in formsets:

            instances = formset_ob.save(commit =False)
            self.last_obj.price = calculatePrice(order_product_instances=instances)
            self.last_obj.save()
            try:
                bookedOut   = sourceCapacityBookOut(self.last_obj,instances,change)
                bookedIn    =destinationCapacityBookIn(self.last_obj,instances,change)
                
                

            except :
                #if not change:
                 #   self.last_obj.delete()
                #else:
                 #   modify_o  = order_modification.objects.get(user = user.objects.get(user_ptr = request.user),order = self.last_obj)
                 #  modify_o.delete()

                raise

            for instance in instances:
                instance.save()

            for bOut in bookedOut:
                bOut.save()

            for bIn in bookedIn:
                bIn.save()
    @transaction.commit_on_success
    def cancelOrder(self,request,queryset):
        message = ""
        for order_i in queryset:
            if isOrderCancelable(order_i):
                try:
                    OrderCancel(order_i)
                    message = "Anulowano"
                    self.log_change(request, order_i, "%s Zostal Anulowany" % order_i)
                except:
                    message = "Nie udalo sie Anulowac"
            else:
                pass

        self.short_description = "Anuluj Zamowienie"
        self.message_user(request, message)
        
    @transaction.commit_on_success
    def archiveOrder(self,request,queryset):
        #Archiwizowac moze tylko supervisor anulowane i zrealizowane
        for order_i in queryset:
            if OrderCanBeArchived(order_i):
                try:
                    orderArchive(order_i)
                    self.log_change(request, order_i, "%s Zostal Zarchiwizowany" % order_i)
                except:
                    pass
        self.short_description = "Archiwizuj Zamowienie"
class Order_productAdmin(admin.ModelAdmin):
    pass
class AddressModelform(ModelForm):
    class Meta:
        model = address

class AddressAdmin(admin.ModelAdmin):
    form = AddressModelform
    @csrf_protect_m
    @transaction.commit_on_success
    def add_view(self, request, form_url='', extra_context=None):
        
        return admin.ModelAdmin.add_view(self, request, form_url=form_url, extra_context=extra_context)
    
    @csrf_protect_m
    @transaction.commit_on_success
    def change_view(self, request, object_id, form_url='', extra_context=None):
        
        if request.method == 'POST':
            if request.POST.has_key('_preview'):
                return HttpResponseRedirect("/admin/storehouse/address_view/%s" %object_id )
        return admin.ModelAdmin.change_view(self, request, object_id, form_url=form_url, extra_context=extra_context)

class DocumentModelform(ModelForm):
    class Meta:
        model = document
    def clean(self):
        order_o = self.cleaned_data['order']
        if order_o:
            #TODO w zaleznosci od stanu zamowienia
            orderSourceCapacityTest(order_o)
            orderDestinationCapacityTest(order_o)
        
        return ModelForm.clean(self)

class DocumentAdmin(admin.ModelAdmin):
    form = DocumentModelform
    exclude=('creator','liquidation','inventory','document_type','storehouse')
    #list_display = ('symbol','country','value')
    list_filter = ('document_type',)
    search_fields=  ('creationDate',)
    def add_view(self, request, form_url='', extra_context=None):
        
        if request.method == 'POST':
            mform_o = DocumentModelform(request.POST)
            if request.POST.has_key('_preview'):
                return HttpResponseRedirect("/order_view/?order_id=%s" %mform_o.data['order'] )
        
        return admin.ModelAdmin.add_view(self, request, form_url=form_url, extra_context=extra_context)
    
    @csrf_protect_m
    @transaction.commit_on_success
    def change_view(self, request, object_id, form_url='', extra_context=None):
        if request.user.has_perm(u'document change_r'):
            return admin.ModelAdmin.change_view(self, request, object_id, form_url=form_url, extra_context=extra_context)
        if request.method == 'POST':
            if request.POST.has_key('_print'):
                return HttpResponseRedirect("/admin/storehouse/print_document/%s" %object_id )
        return HttpResponseRedirect("/document_view/?document_id=%s" %object_id )
    
    def get_form(self, request, obj=None, **kwargs):
        form = super(DocumentAdmin,self).get_form(request, obj,**kwargs)
        try:
            
            user_storehouses = getUserStorehouses(request.user)
        except:
            user_storehouses =   storehouse.objects.get_empty_query_set()
            print sys.exc_info()[1]

        #form.base_fields['storehouse'] = forms.ModelChoiceField(queryset= user_storehouses)
        #TODO filter orders from other storehouses
        storehousesUnderInventory = getInventoriedStorehouses()
        form.base_fields['order'] = forms.ModelChoiceField(queryset= order.objects.filter(Q(storehouse_to__in = user_storehouses)|Q(storehouse_from__in= user_storehouses ))\
        .exclude(Q(state__in = order_state.objects.filter(name__in = ['Anulowany','Zrealizowany']))|Q(storehouse_from__in =storehousesUnderInventory )|Q(storehouse_to__in =storehousesUnderInventory )) )
        return form
    
    def response_add(self, request, obj, post_url_continue=None):
        #TODO complete this
        if obj.order:
            return HttpResponseRedirect("/order_view/?order_id=%i" %obj.order.id )
        elif obj.liquidation:
            super(DocumentAdmin, self).response_add(request, obj)
        elif obj.inventory:
            super(DocumentAdmin, self).response_add(request, obj)
        else:
            super(DocumentAdmin, self).response_add(request, obj)
    @transaction.commit_on_success
    def save_model(self, request, obj, form, change):
        if not change:
            obj.creator = user.objects.get(user_ptr = request.user)
        else:
            doc_mod = document_modification.objects.create(user =user.objects.get(user_ptr = request.user), document = obj )
            doc_mod.save()
        order_state_o = form.cleaned_data['order'].state
        try:
            obj.order = form.cleaned_data['order']
            if order_state_o ==  order_state.objects.get(name = 'Oczekujacy na RW'):
                obj.document_type = document_type.objects.get(symbol = 'RW')
                obj.order.state = order_state.objects.get(name =  'Oczekujacy na PW')
                completeRW(order_in=obj.order,request=request)
                obj.storehouse = storehouse.objects.get(manager = obj.order.partner_from)

            elif order_state_o ==order_state.objects.get(name =  'Oczekujacy na PW'):
                obj.document_type = document_type.objects.get(symbol = 'PW')
                obj.order.state = order_state.objects.get(name = 'Zrealizowany')
                completePW(order_in=obj.order,request=request)
                obj.storehouse = storehouse.objects.get(manager = obj.order.partner_to)

            elif order_state_o == order_state.objects.get(name =  'Oczekujacy na PZ'):
                obj.document_type = document_type.objects.get(symbol = 'PZ')
                obj.order.state = order_state.objects.get(name = 'Zrealizowany')
                completePZ(order_in=obj.order,request=request)
                obj.storehouse = storehouse.objects.get(manager = obj.order.partner_to)

            elif order_state_o ==order_state.objects.get(name =  'Oczekujacy na WZ'):
                obj.document_type = document_type.objects.get(symbol = 'WZ')
                obj.order.state = order_state.objects.get(name = 'Zrealizowany')
                completeWZ(order_in=obj.order,request=request)
                obj.storehouse = storehouse.objects.get(manager = obj.order.partner_from)

            else:
                pass
            obj.order.save()
            obj.save()
        except StorehouseUnderINventory:
            pass
        except:
            print "DocumentAdmin::save_model",sys.exc_info()
            raise

 #TODO filter documents to users documents for user and magazine documents for Manager
    def queryset(self, request):
        try:
            person_o =  person.objects.get(user = user.objects.get(user_ptr = request.user).id)
        except:
            return document.objects.get_empty_query_set()

        if request.user.is_superuser:
            return document.objects.all()

        if request.user.has_perm(u'document storehouse manager'):
            storehouse_o = storehouse.objects.get(manager = person_o)
            return document.objects.filter(storehouse=storehouse_o)

        if isPersonStorehouseStaff(person_in=person_o):
            return document.objects.filter(creator = user.objects.get(user_ptr = request.user))

        return document.objects.get_empty_query_set()
    
    

